package ontocompo.ui.merge;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import ontocompo.ui.MainFrame;
import ontocompo.ui.positioning.JComponentTransfertHandler;
import ontocompo.ui.positioning.PositioningPane;
import ontocompo.ui.screenmanagement.Screen;
import ontocompo.ui.screenmanagement.ScreenConsumer;
import ontocompo.ui.screenmanagement.ScreenFlowSelector;
import ontocompo.ui.screenmanagement.ScreenPossibilities;

public class PlugPane extends JPanel implements ScreenConsumer, Observer {

	private ArrayList<Screen> availabledScreens;
	private PlugSelector plugSelector;
	
	private JPanel workingScreenPanel;
	private JPanel actionsScreenPanel;
	private JList plugDescription;
	private DefaultListModel plugDescriptionData;
	private Screen selectedScreen;
	private JPanel inBulkPane;
	private ArrayList<Operator> operators;
	private JComboBox operatorsList;
	private JButton plugButton;
	
	private MainFrame mf;
	
	public PlugPane(ArrayList<Screen> screens, PlugSelector ps, MainFrame mf) {
		super();
		
		this.operators = new ArrayList<Operator>();
		this.operators.add(new ParallelOperator());
		
		this.availabledScreens = screens;
		this.plugSelector = ps;
		this.plugSelector.addObserver(this);
		
		this.mf = mf;
		
		this.build();
	}
	
	private void build() {
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		
		ScreenPossibilities ep = new ScreenPossibilities(false, null, true, this);
		ep.setButtonMessage("select");
		ep.init();
		ep.updateScreensList(availabledScreens);
		add(ep);
		
		JPanel plugPanel = new JPanel();
		plugPanel.setLayout(new BoxLayout(plugPanel, BoxLayout.X_AXIS));
		add(plugPanel);
		
		workingScreenPanel = new JPanel();
		
		inBulkPane = new JPanel();
		inBulkPane.setLayout(new BoxLayout(inBulkPane, BoxLayout.Y_AXIS));
		workingScreenPanel.add(inBulkPane);
		
		plugPanel.add(workingScreenPanel);
		
		actionsScreenPanel = new JPanel();
		actionsScreenPanel.setLayout(new BoxLayout(actionsScreenPanel, BoxLayout.Y_AXIS));
		
		JPanel plugScreenPanel = new JPanel();
		plugScreenPanel.setLayout(new BoxLayout(plugScreenPanel, BoxLayout.X_AXIS));
		
		operatorsList = new JComboBox(operators.toArray());
		this.operatorsList.setEnabled(false);
		plugScreenPanel.add(operatorsList);
		plugButton = new JButton("Perform operator");
		plugButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				plugAction();
			}
			
		});
		this.plugButton.setEnabled(false);
		plugScreenPanel.add(plugButton);
		actionsScreenPanel.add(plugScreenPanel);
		
//		addNextScreenButton = new JButton("Add a 'Next Screen' button");
//		addNextScreenButton.addActionListener(new ActionListener() {
//
//			@Override
//			public void actionPerformed(ActionEvent arg0) {
//				// TODO Auto-generated method stub
//				addNextScreenbutton();
//			}
//			
//		});
//		actionsScreenPanel.add(addNextScreenButton);
		
		plugPanel.add(actionsScreenPanel);
		
		
		JPanel plugInfoPanel = new JPanel();
		plugInfoPanel.setLayout(new BoxLayout(plugInfoPanel, BoxLayout.Y_AXIS));
		plugInfoPanel.add(new JLabel("Information"));
		plugDescriptionData = new DefaultListModel();
		plugDescription = new JList(plugDescriptionData);
		JScrollPane listScroller = new JScrollPane(plugDescription);
		listScroller.setPreferredSize(new Dimension(60, 40));
		//screenFlowDescription.setEnabled(false);
		plugInfoPanel.add(listScroller);
		plugPanel.add(plugInfoPanel);
	}
	
	private void plugAction() {
		Component first = this.plugSelector.getFirstSelectedComponent();
		Component second = this.plugSelector.getSecondSelectedComponent();
		
		Operator op = (Operator) this.operatorsList.getSelectedItem();
		
//		System.err.println("Before plug action: first: " + first + " --- second: " + second);
		
		Component resultComponent = op.perform(first, second, this.selectedScreen);
		
		if(resultComponent != null) {
			this.mf.removePlugSelector(first);
			this.mf.removePlugSelector(second);
			this.mf.addPlugListener(resultComponent);
		}
		
		this.consume(this.selectedScreen);
		
		this.plugSelector.resetSelection();
//		System.err.println("End of plug action");
	}
	
	@Override
	public void consume(Screen s) {
		// TODO Auto-generated method stub
		this.inBulkPane.removeAll();
		
		this.selectedScreen = s;
		
		ArrayList<Component> inBulkComponents = this.selectedScreen.getInBulkComponents();
		
		for(Component jc: inBulkComponents) {
			this.inBulkPane.add(jc);
		}
		
		this.validate();
	}
	
	private void updateActionList() {
		this.operatorsList.setEnabled(true);
		this.plugButton.setEnabled(true);
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		String state = (String) arg;
		

		if(state.equals("firstComponentSelected")) {
			plugDescriptionData.removeAllElements();
			
			plugDescriptionData.addElement("First Component selected");
			
			plugDescriptionData.addElement("Choose a second one.");
			
			this.plugDescription = new JList(plugDescriptionData);
			
			this.validate();
			
		} else if(state.equals("secondComponentSelected")) {
			plugDescriptionData.removeAllElements();
			
			plugDescriptionData.addElement("First Component selected.");
			
			plugDescriptionData.addElement("Second Component selected.");
			
			plugDescriptionData.addElement("Choose an operator.");
			
			this.plugDescription = new JList(plugDescriptionData);
			
			this.updateActionList();
			
			this.validate();
		} else if(state.equals("cancelFirstComponent")) {
			plugDescriptionData.removeAllElements();
			
			plugDescriptionData.addElement("Choose a first component.");
			
			this.plugDescription = new JList(plugDescriptionData);
			
			this.validate();
		} else if(state.equals("cancelSecondComponent")) {
			plugDescriptionData.removeAllElements();
			
			plugDescriptionData.addElement("First Component selected.");
			
			plugDescriptionData.addElement("Choose a second one.");
			
			
			this.plugDescription = new JList(plugDescriptionData);
			
			this.validate();
		}
	}

}
